
#include <boost/config.hpp>
#include <iostream>
#include <fstream>
#include "ConversionManager.h"
#include "ConversionRoute.h"

#include "BaseTypes/BaseType.h"
#include "BaseTypes/MeshType.h"
#include "BaseTypes/Triangles.h"
#include "BaseTypes/Polygons.h"
#include "BaseTypes/Nurbs.h"
#include "BaseTypes/WingedEdges.h"


#include "Conversion.h"




#include <string>
#include "readObj.h"

#include "gmDisplay/gmDisplay.h"



using namespace geomagick;
using namespace std;
using namespace boost;



int main(int, char *[])
{
        BaseType myType;
        MeshType myMeshType;

	// Create a new ConversionManager
        ConversionManager * TestManager = new ConversionManager();

	// Register BaseTypes at the ConversionManager

//         TestManager->registerBaseType(Nurbs::getTypeId());
//         TestManager->registerBaseType(Triangles::getTypeId());
//         TestManager->registerBaseType(Polygons::getTypeId());
// 	TestManager->registerBaseType(WingedEdges::getTypeId());
// 	//TestManager->registerBaseType(Nurbs::getTypeId());
// 
// 	// Register Conversions at the ConversionManager
// 	TestManager->registerConversion(Triangulizer::getTypeId());
// 	TestManager->registerConversion(NurbsTesselator::getTypeId());
// 	TestManager->registerConversion(WingedEdges2Polygons::getTypeId());
// 	TestManager->registerConversion(Polygons2WingedEdges::getTypeId());
	
	//TestManager->registerConversion(TestConversion4::getTypeId());

	vector<BaseTypeId*> SourceType;
		//SourceType.push_back(BaseType::getTypeId());
		SourceType.push_back(Polygons::getTypeId());
		SourceType.push_back(Nurbs::getTypeId());
	vector<BaseTypeId*> TargetType;
		TargetType.push_back(Triangles::getTypeId());
		TargetType.push_back(Nurbs::getTypeId());

	ConversionRoute CR = TestManager->route(SourceType,TargetType);
	CR.print();

	

	// Get some DEBUG output from the ConversionManager in order to see it worked
        cout << "The registered BaseTypes are : " << TestManager->strGetBaseTypeNames() << "\n";
	cout << "The registered Conversions are : " << TestManager->strGetConversionNames() << "\n";

	ShortestPaths SP = TestManager->getShortestPaths(1);
	for(unsigned int i = 0; i < (SP.distances)->size(); i++) cout << "Distance to " << i <<" : " << (*(SP.distances))[i] << endl;

	for(unsigned int i = 0; i < SP.parents->size(); i++) cout << "Parent of " << i <<" : " << (*(SP.parents))[i] << endl;

	ofstream f("testCG.dot");
	f << TestManager->CGdot() << endl;
	f.close();
	
	f.open("test.dot");
	f << TestManager->dot() << endl;
	f.close();

	cout << "Reading a .obj-file" << endl;
	Polygons* testPolygons = readObj();
	Triangulizer* testTriangulizer = new Triangulizer();
	testPolygons->printStatistic();

	Nurbs* testNurbs = new Nurbs();
	NurbsTesselator* testNurbsTesselator = new NurbsTesselator();
	Triangles* tesselatedNURBS;
	tesselatedNURBS = testNurbsTesselator->process(testNurbs);
	tesselatedNURBS->printStatistic();
	//Triangles* testTriangles = (Triangles*)CR.process(testPolygons);

	

	cout << "OK 1" << endl;
	Polygons2WingedEdges* testP2WE = new Polygons2WingedEdges();
	cout << "OK 2" << endl;
	// WingedEdges* testWE = testP2WE->process(testPolygons);
	cout << "OK 3" << endl;
	// WingedEdges2Polygons* testWE2P = new WingedEdges2Polygons();
	cout << "OK 4" << endl;
	// testWE->printWingedEdges();
	// Polygons* testPolygons2 = testWE2P->process(testWE);
	cout << "OK 5" << endl;
	gmGLDisplay* Display = new gmGLDisplay();
	//Display = new gmGLDisplay();
	//Display->display(testPolygons);
	//Display->init();
	//delete Display;
	//Display = new gmGLDisplay();
	//Display->display(testTriangles);
	//Display->init();
	
	//Display->init();
	
	cout << "Triangulizing" << endl;
	Triangles* testTriangles =  (Triangles*)CR.process(testPolygons);
	cout << "done" << endl;
	testTriangles->printStatistic();
        delete TestManager;

	//delete Display;
	Display = new gmGLDisplay();
	Display->display((Polygons*)testPolygons);
	Display->display((Polygons*)testTriangles);
	Display->init();
	return 0;
	f.open("test.oobj");
	foreach(Polygon curPolygon, *(testPolygons->getPolygonList()) )
	{
		f << "f ";
		foreach(int i, curPolygon.Vertices)
		{
			f  << " " << i ;
		}
		f << (char)(0x0d) << endl;
	}//

	f.close();
	f.open("testv.oobj");
	boost::shared_ptr<vector<Vector3d> > vertexCoordinates = testPolygons->getVertexCoordinates();
	foreach(Vector3d vec, *(vertexCoordinates) )	
 		{
			f  << "v " << vec.x << " "<<vec.y <<" " << vec.z;
			f << (char)(0x0d) << endl;
		}
		
	
	f.close();
	
	
	
	

        return 0;
}
